
#include "data/data.h"


namespace iecas_ns
{
    shared_ptr<CData> CData::sm_intancePtr = nullptr;

    CData::CData()
    {
        m_commonPtr = shared_ptr<CCommon>(CCommon::getInstance());
        m_jsonUsrPtr = shared_ptr<CJsonUsr>(CJsonUsr::getInstance());
        m_routePtr = shared_ptr<CRoute>(CRoute::getInstance());
        m_transPtr = shared_ptr<CTrans>(CTrans::getInstance());
    }

	shared_ptr<CData> CData::getInstance()
	{
		if(sm_intancePtr == nullptr)
		{
			sm_intancePtr = shared_ptr<CData>(new CData());
		}
		return sm_intancePtr;
	}

    bool CData::init(void)
    {
        return true;
    }

    void CData::start(void)
    {
        thread tempThread(&CData::loop, this);
        tempThread.detach();
    }

    void CData::loop(void)
    {
        Value json_data;
        string src_dev, src_data;

        while(true)
        {
            json_data.clear();

            if(m_commonPtr->getDataFront(json_data))
            {
                src_dev = json_data[SRC_DEV].asString();
                src_data = json_data[SRC_DATA].asString();
            
                data_trans(src_data);

                m_commonPtr->delDataFront();
            }

            usleep(1);
        }
    }

    void CData::data_trans(string src_data)
    {
        string data_head, data_body;

        data_head = src_data.substr(0, 5);
        if(data_head == MESG_DEV_HEAD)
        {
            data_body = src_data.substr(5);
            mesg_dev_trans(data_head, data_body);
        }
        else
        {
            order_dev_trans(data_head);
        }
    }

    void CData::mesg_dev_trans(string data_head, string data_body)
    {
        string dest_dev;
        vector<Value> table;
        int dest_fd = -1, i;

        table.clear();

        if(m_transPtr->getTransMesg(data_head, table))
        {
            for(i = 0; i < table.size(); i++)
            {
                dest_dev = table[i][TRANS_MESG_DEST].asString();
                cout << "test m_trans_mesg : " << data_body << " -> " << dest_dev << endl;
                PLOGD << "test m_trans_mesg : " << data_body << " -> " << dest_dev;
                if(m_commonPtr->getDevFdStat(dest_dev, dest_fd))
                {
                    write(dest_fd, data_body.c_str(), data_body.size());
                }
            }
        }
    }

    void CData::order_dev_trans(string data_head)
    {
        order_chg_dev_trans(data_head);
    }

    void CData::order_chg_dev_trans(string data_head)
    {
        vector<Value> table;
        int i;

        table.clear();

        if(m_transPtr->getTransOrderChg(data_head, table))
        {
            for(i = 0; i < table.size(); i++)
            {
                // cout << "test m_trans_order_chg : " << src << " -> " << table1[i][TRANS_ORDER_CHG_MID].asString() << endl;
                // PLOGD << "test m_trans_order_chg : " << src << " -> " << table1[i][TRANS_ORDER_CHG_MID].asString();
                order_out_dev_trans(table[i][TRANS_ORDER_CHG_MID].asString());
            }
        }
    }

    void CData::order_out_dev_trans(string data_head)
    {
        string dest_dev;
        vector<Value> table;
        int dest_fd = -1, i, j;
        uint8_t buffer[MAXDATASIZE]={0};
        Value tmp;

        table.clear();
        tmp.clear();

        if(m_transPtr->getTransOrderOut(data_head, table))
        {
            for(i = 0; i < table.size(); i++)
            {
                dest_dev = table[i][TRANS_ORDER_OUT_DEST].asString();
                cout << "test m_trans_order_out : -> " << dest_dev << endl;
                PLOGD << "test m_trans_order_out : -> " << dest_dev;
                if(m_commonPtr->getDevFdStat(dest_dev, dest_fd))
                {
                    tmp = table[i][TRANS_ORDER_OUT_CONT];
                    if(tmp.isString())
                    {
                        write(dest_fd, tmp.asString().c_str(), tmp.asString().size());
                    }
                    else if(tmp.isArray())
                    {
                        for(j = 0; j < tmp.size(); j++)
                        {
                            buffer[j] = tmp[j].asUInt();
                        }
                        write(dest_fd, buffer, tmp.size());
                    }
                }
            }
        }
    }
}
